package com.tuhu.server.util;


import java.util.*;

public class CollectionUtils {

    public interface Comparator2<T, M> {
        /**
         * 比较T和M是否指代同一业务对象
         *
         * @return 0:相同； 正数:o1>02;  负数:01<02
         */
        int compare(T o1, M o2);
    }

    public interface Function1<T, Boolean>{
        boolean accept(T t);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////  数组集合的操作  ////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////
    public static boolean isEmpty(int[] array) {
        return array == null || array.length == 0;
    }

    public static <T> boolean isEmpty(T[] array) {
        return array == null || array.length == 0;
    }

    public static <T> boolean isNotEmpty(T[] array) {
        return !isEmpty(array);
    }

    public static <T> T getLast(T[] array) {
        if (isEmpty(array)) {
            return null;
        }
        return array[array.length - 1];
    }

    public static <T> int size(T[] array) {
        return array == null ? 0 : array.length;
    }

    public static <T> boolean isValidPos(T[] array, int pos) {
        return isNotEmpty(array) && pos >= 0 && pos < array.length;
    }

    public static <T> T get(T[] array, int pos) {
        if (!isValidPos(array, pos)) {
            return null;
        }
        return array[pos];
    }

    /**
     * 比较内存地址，判断 array对象数组中 是否 存在 target
     * <p>
     * 注:
     * String是引用类型，此方法会比较对象地址
     * 如果判断的对象是String，请使用{@link StringUtils#contains}
     *
     * @return true:存在; false:不存在
     */
    public static <T> boolean contains(T[] array, T target) {
        if (array == null || array.length == 0) {
            return false;
        }

        for (int i = 0; i < array.length; i++) {
            if (array[i] == target) {
                return true;
            }
        }
        return false;
    }

    public static <T> boolean contains(T[] array, T target, Comparator<T> comparator) {
        if (array == null || array.length == 0) {
            return false;
        }

        for (int i = 0; i < array.length; i++) {
            if (comparator.compare(array[i], target) == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 比较int数值，判断 array整形数组中 是否 存在 target
     *
     * @return true:存在; false:不存在
     */
    public static boolean contains(int[] array, int target) {
        if (array == null || array.length == 0) {
            return false;
        }

        for (int i = 0; i < array.length; i++) {
            if (array[i] == target) {
                return true;
            }
        }
        return false;
    }

    public static <T> List<T> toArrayList(T[] array) {
        if (array == null) {
            return null;
        }
        ArrayList<T> arrayList = new ArrayList<>();
        for (int i = 0; i < array.length; i++) {
            arrayList.add(array[i]);
        }

        return arrayList;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////  List集合的操作  ///////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////
    public static <T> boolean isEmpty(List<T> list) {
        return list == null || list.isEmpty();
    }

    public static <T> boolean isNotEmpty(List<T> list) {
        return !isEmpty(list);
    }

    public static <T> boolean isValidPos(List<T> list, int pos) {
        return isNotEmpty(list) && pos >= 0 && pos < list.size();
    }

    //判断pos是否为list的最后一项
    public static <T> boolean isLast(List<T> list, int pos) {
        if (isEmpty(list)) {
            return false;
        }
        return list.size() - 1 == pos;
    }

    public static <T> T get(List<T> list, int pos) {
        if (!isValidPos(list, pos)) {
            return null;
        }
        return list.get(pos);
    }

    public static <T> T getMin(List<T> list, Comparator<T> comparator) {
        if (isEmpty(list)) {
            return null;
        }
        T min = null;
        for (int i = 0; i < CollectionUtils.size(list); i++) {
            T t = list.get(i);
            if (min == null) {
                min = t;
            } else {
                if (comparator.compare(min, t) > 0) {
                    min = t;
                }
            }
        }

        return min;
    }

    public static <T> T getMax(List<T> list, Comparator<T> comparator) {
        if (isEmpty(list)) {
            return null;
        }
        T max = null;
        for (int i = 0; i < CollectionUtils.size(list); i++) {
            T t = list.get(i);
            if (max == null) {
                max = t;
            } else {
                if (comparator.compare(max, t) < 0) {
                    max = t;
                }
            }
        }

        return max;
    }

    public static <T> T getLast(List<T> list) {
        if (isEmpty(list)) {
            return null;
        }
        return list.get(list.size() - 1);
    }

    public static <T> void removeLast(List<T> list) {
        if (isEmpty(list)) {
            return;
        }
        list.remove(list.size() - 1);
    }

    public static <T> int size(List<T> list) {
        return list == null ? 0 : list.size();
    }

    public static <T> boolean contains(List<T> list, T target, Comparator<T> comparator) {
        if (isEmpty(list) || target == null) {
            return false;
        }

        for (int i = 0; i < list.size(); i++) {
            if (comparator.compare(list.get(i), target) == 0) {
                return true;
            }
        }
        return false;
    }

    public static <T> boolean remove(List<T> list, T target, Comparator<T> comparator) {
        if (isEmpty(list) || target == null) {
            return false;
        }

        Iterator<T> iterator = list.iterator();
        while (iterator.hasNext()) {
            T t = iterator.next();
            if (comparator.compare(t, target) == 0) {
                iterator.remove();
                return true;
            }
        }
        return false;
    }

    public static <T, M> boolean contains(List<T> list, M target, Comparator2<T, M> comparator) {
        if (isEmpty(list) || target == null) {
            return false;
        }

        for (int i = 0; i < list.size(); i++) {
            if (comparator.compare(list.get(i), target) == 0) {
                return true;
            }
        }
        return false;
    }

    public static <T, M> boolean remove(List<T> list, M target, Comparator2<T, M> comparator) {
        if (isEmpty(list) || target == null) {
            return false;
        }

        Iterator<T> iterator = list.iterator();
        while (iterator.hasNext()) {
            T t = iterator.next();
            if (comparator.compare(t, target) == 0) {
                iterator.remove();
                return true;
            }
        }
        return false;
    }

    public static <T> List<T> find(List<T> list, Function1<T, Boolean> function1) {
        if (isEmpty(list) || function1 == null) {
            return null;
        }

        List<T> resultList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            T t = list.get(i);
            if (function1.accept(t)) {
                resultList.add(t);
            }
        }
        return resultList;
    }

    public static <T> T findFirst(List<T> list, Function1<T, Boolean> function1) {
        if (isEmpty(list) || function1 == null) {
            return null;
        }

        List<T> resultList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            T t = list.get(i);
            if (function1.accept(t)) {
                resultList.add(t);
            }
        }

        return CollectionUtils.get(resultList, 0);
    }

    public static <T, M> T findFirstByTarget(List<T> list, M target, Comparator2<T, M> comparator) {
        if (isEmpty(list) || target == null) {
            return null;
        }

        for (int i = 0; i < list.size(); i++) {
            if (comparator.compare(list.get(i), target) == 0) {
                return list.get(i);
            }
        }
        return null;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////  Map集合的操作  ////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////
    public static boolean isEmpty(Map map) {
        return map == null || map.isEmpty();
    }

    public static boolean isNotEmpty(Map map) {
        return !isEmpty(map);
    }

    public static <T, M> M get(Map<T, M> map, T key) {
        if (map == null) {
            return null;
        }
        return map.get(key);
    }

    public static <T, M> M get(Map<T, M> map, T key, M defaultValue) {
        if (map == null) {
            return defaultValue;
        }
        return map.get(key);
    }

    /**
     * 计算数据中前 endIndex 个数值的总和
     *
     * @param arr      目标数组
     * @param endIndex 终止位置，包含此位置
     */
    public static int sum(int[] arr, int endIndex) {
        int total = 0;
        for (int i = 0; i <= Math.min(endIndex, arr.length - 1); i++) {
            total += arr[i];
        }
        return total;
    }

    public static int sum(int[] arr) {
        int total = 0;
        for (int i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }

    public static String toString(int[] intArr) {
        if (intArr == null || intArr.length == 0) {
            return "";
        }

        String result = "";
        String tail = ", ";

        for (int i = 0; i < intArr.length; i++) {
            result += intArr[i] + tail;
        }
        if (result.length() > 0) {
            result = result.substring(0, result.length() - tail.length());
        }

        return result;
    }


    public static String toString(String[] stringArr) {
        if (stringArr == null || stringArr.length == 0) {
            return "";
        }

        String result = "";
        String tail = ", ";

        for (int i = 0; i < stringArr.length; i++) {
            result += stringArr[i] + tail;
        }
        if (result.length() > 0) {
            result = result.substring(0, result.length() - tail.length());
        }

        return result;
    }


}
